﻿Imports Microsoft.TeamFoundation.Client
Imports Microsoft.TeamFoundation.VersionControl.Client
Imports System.Collections.Generic

Public Class TFSSearchCodeClass
    Inherits MarshalByRefObject

    Public Delegate Sub ProgressAction(ByVal Progress As Integer)
    Dim ExternalProgress As ProgressAction = Nothing

    Dim colNodes As New List(Of String)

    Public ItemsSource As New List(Of ItemSource)
    Public Folders() As String
    Public SensitiveSearch As Boolean
    Public TimeEmployedAction As Long
    Private Connection As TfsConnection

    Public Event ProgressSearchingFolders(ByVal Progress As Integer)
    Public Event ProgressSearchingText(ByVal Progress As Integer)

    Public Sub New()
        Connection = New TfsConnection
        Console.WriteLine("instancia recibida {0}", My.Application.Info.DirectoryPath)
    End Sub

    Public Sub New(ByVal Login As String, ByVal Password As String, ByVal IpPortOrMachineName As String)

        Connect(Login, Password, IpPortOrMachineName)


    End Sub

    Public Sub Connect(ByVal Login As String, ByVal Password As String, ByVal IpPortOrMachineName As String)

        Connection = New TfsConnection(Login, Password, IpPortOrMachineName)


    End Sub

    ''' <summary>
    ''' Search a text string in all latest versions on nodes and subnodes of files that are stored in TFS source control
    ''' </summary>
    ''' <param name="RootNode"></param>
    ''' <param name="Pattern"></param>
    ''' <param name="TextToSearch"></param>
    ''' <remarks></remarks>
    Public Sub SearchTextInCode(ByVal RootNode As String, ByVal Pattern As String, ByVal TextToSearch As String)

        ItemsSource.Clear()

        TimeEmployedAction = Now.TimeOfDay.TotalSeconds

        Dim MiItemSpec() As ItemSpec = _
            New ItemSpec() {New ItemSpec(RootNode & IIf(Mid(RootNode, Len(RootNode), 1) <> "/", "/", "") & Pattern, RecursionType.Full)}

        Dim MyTFSFoldersSubNodes As Object = _
            Connection.vcs.GetExtendedItems( _
                    MiItemSpec, _
                    DeletedState.NonDeleted, _
                    ItemType.Any)

        Dim items As IEnumerable = MyTFSFoldersSubNodes
        If IsArray(items(0)) Then items = items(0)


        Dim I As Long = 0
        Dim last As Integer = 0

        For Each FolderSubnode As ExtendedItem In items

            I += 1

            Debug.Print(I.ToString & " / " & (UBound(items) + 1).ToString)

            If last <> Int((I / (UBound(items) + 1) * 100)) Then

                last = Int((I / (UBound(items) + 1) * 100))

                If ExternalProgress IsNot Nothing Then

                    ExternalProgress(last)

                Else

                    RaiseEvent ProgressSearchingText(last)

                End If



            End If

            Select Case FolderSubnode.ItemType

                Case ItemType.File

                    Dim itemStream As System.IO.Stream = Connection.vcs.GetItem(FolderSubnode.SourceServerItem).DownloadFile()
                    Dim itemStrRead As New System.IO.StreamReader(itemStream, System.Text.Encoding.Default)
                    Dim lLinea As Long = 0

                    While Not itemStrRead.EndOfStream

                        lLinea += 1

                        Dim linea As String = itemStrRead.ReadLine().ToString

                        Dim boInclude As Boolean = False

                        If Me.SensitiveSearch Then

                            If linea.IndexOf(TextToSearch) <> -1 Then boInclude = True

                        Else

                            If linea.IndexOf(TextToSearch, StringComparison.OrdinalIgnoreCase) <> -1 Then boInclude = True

                        End If



                        If boInclude Then

                            Dim TFSFolder As String = ""
                            Dim TFSFile As String = ""

                            Try
                                TFSFolder = Mid(FolderSubnode.SourceServerItem, 1, InStrRev(FolderSubnode.SourceServerItem, "/") - 1)
                                TFSFile = Mid(FolderSubnode.SourceServerItem, InStrRev(FolderSubnode.SourceServerItem, "/") + 1)

                                ItemsSource.Add(New ItemSource(TFSFolder, TFSFile, FolderSubnode.SourceServerItem, lLinea, linea, FolderSubnode))

                            Catch ex As Exception

                            End Try

                        End If


                    End While

            End Select


        Next

        TimeEmployedAction = Now.TimeOfDay.TotalSeconds - TimeEmployedAction

    End Sub



    ''' <summary>
    ''' Try get a local copy of file stored in tfs control source
    ''' </summary>
    ''' <param name="ServerItemPathAndName"></param>
    ''' <param name="LocalFile"></param>
    ''' <remarks></remarks>
    Public Sub GetLatestVersion(ByVal ServerItemPathAndName As String, ByVal LocalFile As String)
        Try
            Connection.vcs.GetItem(ServerItemPathAndName).DownloadFile(LocalFile)
        Catch ex As Exception
            Throw New Exception(String.Format("Error on 'GetLatestVersion'" & vbCrLf & _
                                 "to get item '{0}' " & vbCrLf & _
                                 "and store on '{1}' " & vbCrLf & _
                                 "Error description: {2}", ServerItemPathAndName, LocalFile, ex.Message.ToString))


        End Try
    End Sub


    Public Sub LoadFoldersOnTFsServer(ByVal Rootnode As String)

        TimeEmployedAction = Now.TimeOfDay.TotalSeconds

        Folders = Nothing

        Dim MiItemSpec() As ItemSpec = _
            New ItemSpec() {New ItemSpec(Rootnode, RecursionType.Full)}

        Dim MyTFSFoldersSubNodes As Object

        Try

            MyTFSFoldersSubNodes = _
                Connection.vcs.GetExtendedItems( _
                        MiItemSpec, _
                        DeletedState.NonDeleted, _
                        ItemType.Folder)

        Catch ex As Exception

            Throw New Exception(ex.Message.ToString)
            Exit Sub

        End Try

        Dim items As IEnumerable = MyTFSFoldersSubNodes
        If IsArray(items(0)) Then items = items(0)

        Dim I As Long = 0
        Dim last As Integer = 0

        For Each FolderSubnode As ExtendedItem In items

            I += 1

            Debug.Print(I.ToString & " / " & (UBound(items) + 1).ToString)

            If last <> Int((I / (UBound(items) + 1) * 100)) Then

                last = Int((I / (UBound(items) + 1)) * 100)

                If ExternalProgress IsNot Nothing Then

                    ExternalProgress(last)

                Else

                    RaiseEvent ProgressSearchingFolders(last)

                End If

            End If

                Select Case FolderSubnode.ItemType

                    Case ItemType.Folder

                    Dim Ind As Integer = 0

                    Try

                        Ind = Folders.Length - 1
                        Ind = Ind + 1

                    Catch ex As Exception


                    End Try


                    ReDim Preserve Folders(Ind)
                    Folders(Ind) = FolderSubnode.SourceServerItem

                End Select

        Next

        TimeEmployedAction = Now.TimeOfDay.TotalSeconds - TimeEmployedAction

    End Sub
    ''' <summary>
    ''' Useful when works in local and remote mode to difference betwen local or remote instances by computer name
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetComputerName(Optional ByVal ShowsMessageAtServerConsole As Boolean = False) As String
        If ShowsMessageAtServerConsole Then
            Console.WriteLine(Now.TimeOfDay.ToString & ": GetComputerName from " & MyBase.GetHashCode())
        End If
        Return My.Computer.Name
    End Function

    Public Sub ProgressAssign(ByVal proc As ProgressAction)

        ExternalProgress = proc

    End Sub


End Class
